#include "log.h"
#include <iostream>
#include <ctime>

Logger& Logger::getInstance() {
    static Logger instance;
    return instance;
}

Logger::Logger() = default;

Logger::~Logger() {
    if (logfile_.is_open()) logfile_.close();
}

void Logger::setLogFile(const std::string& filename) {
    std::lock_guard<std::mutex> lock(mutex_);
    logfile_.open(filename, std::ios::app);
}

void Logger::log(LogLevel level, const std::string& message) {
    std::lock_guard<std::mutex> lock(mutex_);
    std::string prefix = getPrefix(level);
    std::string timeStr = getCurrentTime();
    if (logfile_.is_open()) {
        logfile_ << "[" << timeStr << "] " << prefix << message << std::endl;
    } else {
        std::cerr << "[" << timeStr << "] " << prefix << message << std::endl;
    }
}

void Logger::error(const std::string& message)   { log(LogLevel::ERROR, message); }
void Logger::warning(const std::string& message) { log(LogLevel::WARNING, message); }
void Logger::info(const std::string& message)    { log(LogLevel::INFO, message); }
void Logger::notify(const std::string& message)  { log(LogLevel::NOTIFY, message); }

std::string Logger::getPrefix(LogLevel level) {
    switch (level) {
        case LogLevel::ERROR:   return "[ERROR] ";
        case LogLevel::WARNING: return "[WARNING] ";
        case LogLevel::INFO:    return "[INFO] ";
        case LogLevel::NOTIFY:  return "[NOTIFY] ";
        default:                return "[UNKNOWN] ";
    }
}

std::string Logger::getCurrentTime() {
    std::time_t now = std::time(nullptr);
    char buf[20];
    std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
    return buf;
}